<template>
   <!-- 上传图片 -->
   <div>
      <!-- limit	最大允许上传个数 -->
      <!-- action	必选参数，上传的地址 给它一个 # 就不会报错了-->
      <!-- on-preview	点击文件列表中已上传的文件时的钩子 预览-->
      <!-- file-list 是上传的文件列表，可以绑定到上传组件上，让上传组件来显示 -->
      <!-- :class 后边的变量为 布尔值，为 true，隐藏， 为 false 显示 -->
      <!-- on-remove	文件列表移除文件时的钩子 -->
      <!-- upload 组件显示的是 fileList 的内容 -->
      <!-- on-change	文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用 -->
      <!-- before-upload	上传文件之前的钩子，参数为上传的文件，
      若返回 false 或者返回 Promise 且被 reject，则停止上传。 -->
      <!-- http-request	覆盖默认的上传行为，可以自定义上传的实现 -->
      <el-upload
         list-type="picture-card"
         :limit="1"
         action="#"
         :on-preview="preview"
         :file-list="fileList"
         :class="{ disabled: fileComputed }"
         :on-remove="handleRemove"
         :on-change="changeFile"
         :before-upload="beforeUpload"
         :http-request="upload"
      >
         <i class="el-icon-plus"></i>
      </el-upload>
      <!-- 预览图片弹层 -->
      <!-- 因为 showDialog 是 data 属性，不是 props 属性，所以可以用 sync -->
      <el-dialog :visible.sync="showDialog" title="图片预览">
         <img :src="imgUrl" alt="" style="width:100%" />
      </el-dialog>
      <!-- 进度条组件 -->
      <!-- percentage  表示进度条对应的百分比，必填，必须在 0-100 -->
      <el-progress
         style="width:180px"
         :percentage="percent"
         v-if="showPercent"
      ></el-progress>
   </div>
</template>

<script>
// 引入腾讯云 cos 包
import COS from 'cos-js-sdk-v5'
// 实例化cos对象，得到一个上传对象，对象就是后边上传所需要的
const cos = new COS({
   // 身份识别 ID
   SecretId: 'AKIDf8MQJwINBjzznPkoiU8YkfJgmb9RSCfr',
   // 身份秘钥
   SecretKey: 'wbz6wVnoXzA4h26tQhgOqZ2E9nAF9pFO'
})
export default {
   data() {
      return {
         // file-list	上传的文件列表,
         // 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
         fileList: [],
         showDialog: false,
         // 保存 图片 地址
         imgUrl: '',
         // 把确定上传的 uid 记下来
         currentFileUid: null,
         // 记录当前的百分比
         percent: 0,
         showPercent: false
      }
   },
   computed: {
      fileComputed() {
         //   如果它为 true 表示不应该显示 + 号,判断当前的数量是不是
         return this.fileList.length === 1
      }
   },
   methods: {
      // 预览
      preview(file) {
         // 拿到它的 url 地址
         // console.log(file.url)
         this.imgUrl = file.url
         this.showDialog = true
      },
      // 删除的钩子
      handleRemove(file, fileList) {
         // file 要删除的文件
         // console.log(file)
         // fileList 删过之后的文件
         // console.log(fileList)
         // 需要根据上边两个参数的删除的变化而变化
         // console.log(this.fileList)
         // 将当前的删除的文件排除在外，得到一个新数组，
         // 为空，没有长度，为false，加号显示
         this.fileList = this.fileList.filter(
            item => item.uid !== file.uid
         )
         // 第二种方式
         // this.fileList = fileList
      },
      // 添加图片
      // 不能用 push ，因为这个钩子会执行多次
      changeFile(file, fileList) {
         // file 是当前的文件
         // console.log(file)
         // fileList 是当前的最新数组
         // console.log(fileList)
         // 但是上边两个变化还是没有改变当前的 fileList
         // console.log(this.fileList)
         // console.log(fileList.length)  // 第一次 1 第二次 0
         // 如果当前的 fileList 没有该文件，就往里进行追加
         // 因为现在还没有上传，action 是个#，所以第二次进来的数据 一定是空的
         // 如果完成上传动作，第一次进入 和 第二次进入，
         // fileList 的长度都是 1，应该都有数据
         // 上传成功，数据才能进来，腾讯云 cos
         this.fileList = fileList.map(item => item)
      },
      // 上传前的检查
      beforeUpload(file) {
         // console.log(file)
         // 检查文件类型
         const types = [
            'image/jpeg',
            'image/gif',
            'image/bmp',
            'image/png'
         ]
         // if(!types.includes(file.type))
         if (!types.some(item => item === file.type)) {
            // 如果不存在
            // 上传终止
            this.$message.error('上传图片只能是 JPG、GIF、BMP、PNG 格式!')
            return false
         }
         // 检查文件大小   1M = 1024KB  1KB = 1024B
         const maxSize = 5 * 1024 * 1024
         if (file.size > maxSize) {
            // 超过了限制的文件大小
            this.$message.error('上传的文件大小不能大于5M')
            return false
         }
         // 确定当前上传的就是这个 文件
         // console.log(file)
         // 把确定上传的 uid 记下来
         this.currentFileUid = file.uid
         // 确定上传了显示进度条
         this.showPercent = true
         // 如果不 return true 默认的是 undefined 还是false
         return true
      },
      // 上传
      upload(params) {
         // 拿到上传的文件
         // console.log(params.file)
         if (params.file) {
            // 执行上传操作
            cos.putObject(
               {
                  // 上传的腾讯云 --> 哪个存储桶，文件，格式，名称，回调
                  // 存储桶
                  Bucket: 'xuetf-1-1307244531',
                  // 地域名称
                  Region: 'ap-beijing',
                  // 对象在存储桶中的唯一标识，文件名
                  Key: params.file.name,
                  // 要上传的文件对象
                  Body: params.file,
                  // 上传的模式类型，默认标准模式
                  StorageClass: 'STANDARD',
                  // onProgress	进度的回调函数，进度回调响应对象（progressData）
                  onProgress: params => {
                     // console.log(params)
                     this.percent = params.percent * 100
                  }
               },
               (err, data) => {
                  // data 处理返回的数据
                  // console.log(err || data)
                  // data 有状态为 200 代表成功
                  if (!err && data.statusCode === 200) {
                     // 此时说明文件上传成功 ，获取成功的返回地址
                     // fileList 才能显示到上传组件，
                     // 要将fileList 数据中的 url 地址，变成现在上传成功的地址
                     // 目前虽然是一张图片，fileList 是一个数组
                     // 需要知道当前上传成功的是哪一张图片
                     this.fileList = this.fileList.map(item => {
                        // 找谁的 uid 等于刚才记录下来的id
                        if (item.uid === this.currentFileUid) {
                           // 将成功的地址赋值给原来的 url 属性
                           // upload: true 表示这张图片上传完毕，为后期应用的时候做标记
                           // 保存 --> 图片有大有小 --> 上传速度有快有慢
                           // -->根据这个upload决定是否去保存
                           return {
                              url: 'http://' + data.Location,
                              upload: true
                           }
                        }
                        return item
                        // 将上传成功的地址回写到 fileList 中，fileList 变化
                        // --> upload 组件就会根据它的变化而去渲染视图
                     })
                     // 关闭进度条，重置百分比
                     setTimeout(() => {
                        this.showPercent = false
                        this.percent = 0
                     }, 2000)
                  }
               }
            )
         }
      }
   }
}
</script>

<style>
.disabled .el-upload--picture-card {
   display: none;
}
</style>
